package
{
	import flash.geom.Point;
	
	import org.flixel.*;
	
	public class SourceBeam extends FlxSprite
	{
		protected var BEAM_THICKNESS:int = 20;
		protected var beamColor:uint;
		protected var beamElement:int;
		protected var isConnected:Boolean;
		protected var forge:SourceForge;
		
		
		public function SourceBeam(
				startIndex:int, 		
				forge:SourceForge, 		
				startsOnArrow:Boolean,	 // holy cow
				endsOnArrow:Boolean,	 // so hacky
				element:int, 			
				cellLength:int, 		
				direction:int)			
		{
			/*
			We're just given the source x,y.  However, depending on direction, and since we 
			can't draw rectangles backwards from their point of origin, we have to set
			the actual x/y first.  So north beams are drawn like south beams, west like east.
			
			If cell length is zero, this will certainly throw an error.
			
			There are a few special cases:
			If it ends in a forge, we draw an extra five pixels.  This is for case in which 
			the plumesource is right next to the sourceforge.
			
			If we start on a arrow, we'll start on the midpoint of the starting index.
			If end end on an arrow, we'll end on the midpoint of the ending index.
			
			*/
			var p:Point = GameState.getPointFromIndex(startIndex);

			var beamLength:int = cellLength * GameState.CELL_SIZE;
			var extraLength:int = (forge != null) ? 5 : 0;
			beamLength += extraLength;
			
			if (endsOnArrow) {
				beamLength -= (GameState.CELL_SIZE / 2);
			}
			
			if (startsOnArrow) {
				beamLength += (GameState.CELL_SIZE / 2);
			}
			
			switch (direction) {
				case Direction.NORTH:
					x = p.x + ((GameState.CELL_SIZE - BEAM_THICKNESS) / 2);
					y = p.y - beamLength;
					
					if (startsOnArrow) {
						y += (GameState.CELL_SIZE / 2);
					}
					break;
				case Direction.SOUTH:
					x = p.x + ((GameState.CELL_SIZE - BEAM_THICKNESS) / 2);
					y = p.y + GameState.CELL_SIZE;
					
					if (startsOnArrow) {
						y -= (GameState.CELL_SIZE / 2);
					}
					break;
				case Direction.WEST:
					x = p.x - beamLength;
					y = p.y + ((GameState.CELL_SIZE - BEAM_THICKNESS) / 2);
					
					if (startsOnArrow) {
						x += (GameState.CELL_SIZE / 2);
					}
					break;
				case Direction.EAST:
					x = p.x + GameState.CELL_SIZE;
					y = p.y + ((GameState.CELL_SIZE - BEAM_THICKNESS) / 2);
					
					if (startsOnArrow) {
						x -= (GameState.CELL_SIZE / 2);
					}
					break;
				default:
					break;
			}
			
			beamElement = element;
			
			switch(beamElement) {
				case Elemental.EARTH:
					color = 0x94E01B;
					break;
				case Elemental.LIGHT:
					color = 0xF7FF9C;
					break;
				case Elemental.WATER:
					color = 0x09A3E6;
					break;
				case Elemental.WIND:
					color = 0xCCDEE6;
					break;
				default:
					color = 0x8D38B5;
					break;
			}
			
			makeGraphic(beamLength, beamLength,0x000000,true);
			
			// depends on direction
			switch(direction) {
				case Direction.NORTH:
					drawRect(0, 0, BEAM_THICKNESS, beamLength, color, 0.5);
					break;
				case Direction.SOUTH:
					drawRect(0, 0, BEAM_THICKNESS, beamLength, color, 0.5);
					break;
				case Direction.WEST:
					drawRect(0, 0, beamLength, BEAM_THICKNESS, color, 0.5);
					break;
				case Direction.EAST:
					drawRect(0, 0, beamLength, BEAM_THICKNESS, color, 0.5);
					break;
				default:
					break;
			}
			
			this.forge = forge;
			isConnected = true;
			
		}
		
		public override function update():void {
			super.update();	
		}
		
		public function get element():int {
			return beamElement;
		}
		
		public function set connected(b:Boolean):void {
			isConnected = b;
		}
		
		public function get connected():Boolean {
			return isConnected;
		}
		
		public function disconnect():void {
			if (forge != null) {
				forge.removeSource(beamElement);
				isConnected = false;
				forge = null;
			}
		}
	}
}